package com.songshuai.webapi.jobapi.service.impl;

import com.alibaba.fastjson.JSON;
import com.songshuai.webapi.jobapi.common.enumerations.JobType;
import com.songshuai.webapi.jobapi.dao.edumaster.TpoSyncDataLogMapper;
import com.songshuai.webapi.jobapi.dto.base.QueryResponse;
import com.songshuai.webapi.jobapi.dto.edu.CourseScheduleDto;
import com.songshuai.webapi.jobapi.dto.productcenter.CourseBindDto;
import com.songshuai.webapi.jobapi.model.edu.TpoSyncDataLog;
import com.songshuai.webapi.jobapi.service.JobNetPostService;
import com.songshuai.webapi.jobapi.service.SyncLogService;
import com.songshuai.webapi.jobapi.util.Util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Auther: Administrator
 * @Date: 2018/11/8 0008 14:47
 * @Description:
 */
@Component
@Slf4j
public class SyncLogServiceImpl implements SyncLogService {

    @Autowired
    TpoSyncDataLogMapper dataLogMapper;

    @Autowired
    JobNetPostService postService;

    @Override
    public int AddSyncLog(Integer dataType, Object reqData, Integer dataId, Integer dataResult) {
        TpoSyncDataLog dataLog=new TpoSyncDataLog();
        dataLog.setCreateTime(new Date());
        dataLog.setDataId(dataId);
        dataLog.setDataType(dataType);
        dataLog.setRequestData(JSON.toJSONString(reqData));
        dataLog.setRequestResult(dataResult);
        Integer result= dataLogMapper.addSyncLog(dataLog);
        return result;
    }

    /**
     *
     * @param dataType
     * @param scheduleDtos
     * @return
     */
    @Override
    public int AddLogs(Integer dataType, List<CourseScheduleDto>scheduleDtos, Map<String,Boolean> postResult){
        Integer res=0;
        if(scheduleDtos==null||scheduleDtos.size()==0){
            return res;
        }
        List<TpoSyncDataLog>logs=new ArrayList<>();
        for(CourseScheduleDto scheduleDto:scheduleDtos){
            try{
                Integer execResult=0;
                if(postResult!=null){
                    Boolean mapValue=postResult.getOrDefault(String.valueOf(scheduleDto.getLesson_id()),false);
                    if(mapValue){
                        execResult=1;
                    }
                }
                TpoSyncDataLog dataLog=new TpoSyncDataLog();
                dataLog.setCreateTime(new Date());
                dataLog.setDataId(Integer.parseInt(scheduleDto.getLesson_id()));
                dataLog.setDataType(dataType);
                dataLog.setRequestData(JSON.toJSONString(scheduleDto));
                dataLog.setRequestResult(execResult);
                logs.add(dataLog);
            }catch (Exception ex){
                log.info("add logs Errors",ex);
            }
        }
        if(logs!=null&&logs.size()>0){
            try{
                dataLogMapper.addSyncLogs(logs);
            }catch (Exception ex){
                log.error("Add sync Logs",ex);
            }

        }
        return res;
    }

    @Override
    public int AddCourseLogs(Integer dataType, List<CourseBindDto>courseBindDtos, Map<String,Boolean> postResult){
        Integer res=0;
        if(courseBindDtos==null||courseBindDtos.size()==0){
            return res;
        }
        List<TpoSyncDataLog>dataLogs=new ArrayList<>();
        for(CourseBindDto scheduleDto:courseBindDtos){
            try{
                Integer execResult=0;
                if(postResult!=null){
                   Boolean mapValue= postResult.getOrDefault(String.valueOf(scheduleDto.getCrm_course_id()),false);
                   if(mapValue){
                       execResult=1;
                   }
                }
                TpoSyncDataLog dataLog=new TpoSyncDataLog();
                dataLog.setCreateTime(new Date());
                dataLog.setDataId(scheduleDto.getCrm_course_id().intValue());
                dataLog.setDataType(dataType);
                dataLog.setRequestData(JSON.toJSONString(scheduleDto));
                dataLog.setRequestResult(execResult);
                dataLogs.add(dataLog);
            }catch (Exception ex){
                log.info("add logs Errors",ex);
            }
        }
        if(dataLogs!=null&&dataLogs.size()>0){
            dataLogMapper.addSyncLogs(dataLogs);
        }
        return res;
    }

    @Override
    public int RemoveLogByDate(String begin) {
        Integer retData = 0;
        if (begin == null || begin.length() == 0) {
            return retData;
        }
        Date beginDate = Util.ChangeStringToDate(begin,"yyyy-MM-dd HH:mm:ss");
        if(beginDate==null){
            beginDate=Util.ChangeStringToDate(begin,"yyyy-MM-dd");
        }
        if(beginDate==null){
            return  retData;
        }
        retData=dataLogMapper.remvoeSyncLog(begin);
        return retData;
    }

    /**
     * 同步日志
     * @param begin
     * @return
     */
    @Override
    public int syncLogs(String begin){
        Integer retData=0;
        if(begin==null||begin.length()==0){
            begin=Util.ChangeDateToString(new Date(),"yyyy-MM-dd");
        }
        int pageIndex=1;
        int pageSize=10;
        int beginId=0;
        List<TpoSyncDataLog>logs=dataLogMapper.selectFailerLogs(begin,3,beginId,pageSize);
        while (logs!=null&&logs.size()>0){
            try{
                beginId=logs.get(logs.size()-1).getId();
                retData+=dealLogs(logs);
            }catch (Exception ex){}
            if(logs.size()<pageSize||pageIndex>100){
                break;
            }
            pageIndex++;
            logs=dataLogMapper.selectFailerLogs(begin,3,beginId,pageSize);
        }
        return retData;
    }

    /**
     * 处理日志
     * @param logs
     * @return
     */
    private int dealLogs(List<TpoSyncDataLog>logs){
        Integer retData=0;
        if(logs==null||logs.size()==0){
            return retData;
        }
        Map<Integer,List<TpoSyncDataLog>>logMaps=new HashMap<>();
        for(TpoSyncDataLog itm:logs){
            List<TpoSyncDataLog>logList=logMaps.getOrDefault(itm.getDataType(),null);
            if(logList==null){
                logList=new ArrayList<>();
                logMaps.put(itm.getDataType(),logList);
            }
            logList.add(itm);
        }

        for(Integer k:logMaps.keySet()){
            StringBuilder sbLogs=new StringBuilder();
            String reqUrl="";
            if(k== JobType.CourseBind.getCode()){
                reqUrl="course/courseBind";
            }else if(k.equals(JobType.CourseHisSchedule.getCode())
                    ||k.equals(JobType.CourseSchedule.getCode())
                    ||k.equals(JobType.CourseShitingSchedule.getCode())){
                reqUrl="course/courseSchedule";
            }
            if(reqUrl.length()==0){
                continue;
            }
            List<TpoSyncDataLog> logList=logMaps.get(k);
            for(TpoSyncDataLog dataLog:logList){
                sbLogs.append(dataLog.getRequestData()+",");
            }
            String strLogs=sbLogs.toString();
            if(strLogs.length()<=0){
                continue;
            }
            List<Integer>logIds=logList.stream().map(TpoSyncDataLog::getId).distinct().collect(Collectors.toList());
            strLogs=strLogs.substring(0,strLogs.length()-1);
            Map<String,String> parms=new HashMap<>();
            parms.put("list","["+strLogs+"]");
            QueryResponse<Map<String,Boolean>> resMap= postService.PostFormData(parms,reqUrl);
            Map<String,Boolean>mapResult= resMap.getData();
            if(mapResult==null||mapResult.size()==0){
                retData=dataLogMapper.modifyFailLogFail(logIds);
                continue;
            }
            //获取成功或失败的数据
            List<Integer>failIds=new ArrayList<>();
            List<Integer>successIds=new ArrayList<>();
            for(TpoSyncDataLog mLog:logList){
                if(mapResult.getOrDefault(mLog.getDataId().toString(),false)){
                    successIds.add(mLog.getId());
                }else {
                    failIds.add(mLog.getId());
                }
            }
            //
            if(failIds.size()>0){
                retData+=dataLogMapper.modifyFailLogFail(failIds);
            }
            if(successIds.size()>0){
                retData+=dataLogMapper.modifyFailLogSuccess(successIds);
            }
        }
        return retData;
    }
}
